package com.aabbc.redis.controller;

import com.aabbc.redis.entity.User;
import com.aabbc.redis.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RLock;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * UserController
 *
 * @author: <a href="mailto:chenfenghai@oristartech.com">chenfenghai</a>
 * @version: 1.0
 * @date: 2019-11-08 17:13
 */
@Slf4j
@RestController
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RedisTemplate<String, Serializable> redisCacheTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("/testRedisson")
    public String testRedisson() throws InterruptedException {
        String key = "testRedisson";
        RBlockingQueue<String> codeQueue = redissonClient.getBlockingQueue(key);
        if(codeQueue.size() <= 10){
            CompletableFuture.runAsync(() -> userService.asynAddCode(key));
        }
        String code = codeQueue.poll(10, TimeUnit.SECONDS);
        log.info("poll = {}, size = {}", code, codeQueue.size());
        return code;
    }


    @GetMapping("/test")
    public User test() {
        String name = stringRedisTemplate.opsForValue().get("geekdigging");
        log.info("当前获取stringRedisTemplate对象：{}", name);
        if(name == null) {
            stringRedisTemplate.opsForValue().set("geekdigging", "https://www.geekdigging.com/");
        }

        User user = (User)redisCacheTemplate.opsForValue().get("geekdigging.com");
        log.info("当前获取redisCacheTemplate对象：{}", user);
        if(user == null) {
            redisCacheTemplate.opsForValue().set("geekdigging.com", new User(1L, "geekdigging", 18));
        }
        return user;
    }

    @GetMapping("/clear")
    public String clear(){
        redisCacheTemplate.delete("geekdigging");
        redisCacheTemplate.delete("geekdigging.com");
        userService.deleteAll1();
        return "success";
    }

    @PostMapping("/save")
    public User save() {
        User user = userService.save(new User(4L, "4geekdigging.com", 35));
        log.info("当前 save 对象：{}", user);
        return user;
    }

    @GetMapping("/get")
    public User get() {
        User user = userService.get(4L);
        log.info("当前 get 对象：{}", user);
        return user;
    }

    @DeleteMapping("/del")
    public String del() {
        userService.delete(4L);
        return "success";
    }

    @GetMapping("/lock1")
    public String lock1(){
        return getLockTime();
    }

    @GetMapping("/lock2")
    public String lock2(){
        return getLockTime();
    }

    @GetMapping("/lock3")
    public String lock3(){
        return getLockTime();
    }


    private String getLockTime(){
        String str = null;
        log.info("getLockTime...");
        //创建所
        RLock lock = redissonClient.getLock("getLockTime");
        //加锁
        lock.lock(30L, TimeUnit.SECONDS);
        try {
            log.info("locked");
            Thread.sleep(5000);
            str = Instant.now().toString();
        }
        catch (InterruptedException e){
            log.error("", e);
        }
        finally {
            //释放锁
            lock.unlock();
        }
        log.info("getLockTime done");
        return str;
    }
}
